package org.vectrics.recruiter.reporting;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;

import org.apache.log4j.Logger;
import org.hibernate.Query;
import org.vectrics.DataException;
import org.vectrics.hibernate.Filter;
import org.vectrics.hibernate.ThreadProperties;
import org.vectrics.provider.CoreServiceLocator;

/**
 * Base class for building Hibernate queries that count records between particular times.
 * @author Mike Moore
 *
 */
abstract public class TimeQuery {
	private Logger log = Logger.getLogger(this.getClass());
	
	public int getMonthCount(int year, int month) {
		log.info("getMonthCount()" +
				"\r\n year = " + year +
				"\r\n month = " + month
				);
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(0);
		
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, month);
		calendar.set(Calendar.DATE, 1);
		Date startDate = calendar.getTime();

		calendar.roll(Calendar.MONTH, true);
		Date endDate = calendar.getTime();

		int count = this.getPeriodCount(startDate, endDate);
		return(count);
	}
	
	public int getYearCount(int year) {
		Calendar calendar = Calendar.getInstance();
		calendar.setTimeInMillis(0);
		calendar.set(Calendar.YEAR, year);
		calendar.set(Calendar.MONTH, 0);
		calendar.set(Calendar.DATE, 1);
		
		Date startDate = calendar.getTime();
		calendar.roll(Calendar.YEAR, true);
		Date endDate = calendar.getTime();
		
		int count = this.getPeriodCount(startDate, endDate);
		return(count);
	}

	protected abstract Filter getFilter(Date startTime, Date endTime);
	
	protected int getPeriodCount(Date startTime, Date endTime) {
		Filter filter = getFilter(startTime, endTime);
		
		SimpleDateFormat format = CoreServiceLocator.getDateFormat().getDateFormatRoundToMinute(CoreServiceLocator.getConfiguration().getDefaultLocale());
		log.info("getPeriodCount():" +
				 "\r\n - Start: " + format.format(startTime) + 
				 "\r\n - End:   " + format.format(endTime) +
				 "\r\n- Statement = " + filter.getStatement());
		Query query = filter.createQuery(ThreadProperties.getSession());
		int count = 0;
		Iterator results = query.iterate();
		if (results == null) {
			throw new DataException("Method does not define logic for criteria");
		}
		else {
			while ( results.hasNext() ) {
				Object row = (Object)results.next();
				Long countInteger = (Long)row;
				count = countInteger.intValue();
			}
		}
		return(count);
	
	}
	
}

